<?php
declare(strict_types=1);

namespace think;

use think\facade\Config;
use think\facade\View;

/**
 * Addons
 * 插件模块基类
 * @author 心衍
 */
abstract class Addons
{
    // 当前插件标识
    protected $name;
    // 插件路径
    protected $addon_path;
    // 插件配置
    protected $addon_config;

    protected $config;

    // 插件信息
    protected $addon_info;

    /**
     * 构造函数
     * @param \think\App $app
     */
    public function __construct(){
        $this->name = $this->getName();
        $this->addon_path = addons_path($this->name);
        $this->addon_info = $this->getInfo();
        // 控制器初始化
        $this->initialize();
    }

    // 初始化
    protected function initialize(){
        //
    }

    /**
     * 获取插件标识
     * @return mixed|null
     */
    final protected function getName(){
        if ($this->name) {
            return $this->name;
        }
        $class = get_class($this);
        list(, $name, ) = explode('\\', $class);
        return strtolower($name);
    }

    /**
     * 插件基础信息
     * @return array
     */
    final public function getInfo(){
        $info = Config::get("addoninfo_{$this->name}", []);
        if ($info) {
            return $info;
        }

        $info = [];
        $info_file = $this->addon_path . 'info.ini';
        if (is_file($info_file)) {
            $info = parse_ini_file($info_file, true, INI_SCANNER_TYPED) ?: [];
        }
        Config::set($info, "addoninfo_{$this->name}");
        return $info ?: [];
    }

    /**
     * 获取配置信息
     * @return array|mixed
     */
    final public function getConfig($type = false){
        $config = Config::get("addonconfig_{$this->name}");
        if ($config) {
            return $config;
        }
        $config = [];
        $config_file = $this->addon_path . 'config.php';
        if (is_file($config_file)) {
            $config = include $config_file;
            if (is_array($config)) {
                $config = array_combine(array_column($config,'name'),array_column($config,'value'));
            }
        }
        Config::set($config, "addonconfig_{$this->name}");
        return $config;
    }

    /**
     * 设置插件信息数据
     * @param $name
     * @param array $value
     * @return array
     */
    final public function setInfo($name = '', $value = []){
        if (empty($name)) {
            $name = $this->getName();
        }
        $info = $this->getInfo($name);
        $info = array_merge($info, $value);
        Config::set($info,"addoninfo_{$name}");
        return $info;
    }

    /**
     * 设置配置数据
     * @param $name
     * @param array $value
     * @return array
     */
    final public function setConfig($name = '', $value = []){
        if (empty($name)) {
            $name = $this->getName();
        }
        $config = $this->getConfig($name);
        $config = array_merge($config, $value);
        Config::set($config,"addonconfig_{$name}");
        return $config;
    }

    /**
     * 检查基础配置信息是否完整
     * @return bool
     */
    final public function checkInfo(){
        $info = $this->getInfo();
        $info_check_keys = ['name', 'title', 'intro', 'author', 'version', 'state'];
        foreach ($info_check_keys as $value) {
            if (!array_key_exists($value, $info)) {
                return false;
            }
        }
        return true;
    }

    final public function addonPath($dir){
        $dir = str_replace('/', DS, $dir?$dir.'/':'');
        return $this->addon_path . $dir;
    }

    //必须实现安装插件方法
    abstract public function install();

    //必须实现卸载插件方法
    abstract public function uninstall();

    //必须实现启用插件方法
    abstract public function enable();

    //必须实现停用插件方法
    abstract public function disable();
}
